//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#include "Graphics/Systems/BatchRender.h"
#include "Graphics/Systems/GraphicsEngine.h"

namespace Engine
{
namespace Graphics
{
	
/*
=================================================
	constructor
=================================================
*/
	BatchRender::BatchRender (const EngineSubSystemsRef ess) :
		BaseObject(ess), _changed(false), _scissorTest(false)
	{}
		
/*
=================================================
	destructor
=================================================
*/
	BatchRender::~BatchRender ()
	{}
	
/*
=================================================
	ScissorTest
=================================================
*/
	void BatchRender::ScissorTest (bool enabled)
	{
		_scissorTest = enabled;

		if ( _scissorTest and _scissor.Empty() )
		{
			_scissor.SetDefault( ESS()->GetGraphicsEngine()->GetViewport()->ViewRect() );
		}
	}
	
/*
=================================================
	Flush
=================================================
*/
	void BatchRender::Flush ()
	{
		StateManager * sm = ESS()->GetGLStateManager();

		if ( _changed )
		{
			_changed = false;
		}

		if ( _vertices.Empty() or _indices.Empty() )
			return;

		FOR( i, _batches )
		{
			_batches[i].material.Apply( sm );

			sm->BindVertexArray( _attribs( _batches[i].attribIndex ).second,
									((uint)_vertices.ptr()) + _batches[i].vertOffset );

			sm->BindIndexBuffer( 0 );
			sm->DrawElements( _batches[i].primitive, _batches[i].indexCount, gl_index::UINT16,
							  MovePointer<uint8>( _indices.ptr(), _batches[i].indexOffset ) );
		}
	}
	
/*
=================================================
	Clear
=================================================
*/
	void BatchRender::Clear ()
	{
		_batches.ClearMem();
		_vertices.ClearMem();
		_indices.ClearMem();
		_changed = true;
	}
	
/*
=================================================
	GetBatch
=================================================
*/
	bool BatchRender::GetBatch (uint index, OUT BatchData &data) const
	{
		CHECK_ERR( index < _batches.Count() );

		Batch const &	batch = _batches[ index ];

		data.material	= batch.material;
		data.primitive	= batch.primitive;

		data.indices.Copy(  uni_array<const uint16>( MovePointer<uint16>( _indices.ptr(), batch.indexOffset ), batch.indexCount ) );
		data.vertices.Copy( uni_array<const uint8>(  MovePointer<uint8>(  _vertices.ptr(), batch.vertOffset ), batch.vertexCount ) );

		return true;
	}

	
}	// Graphics
}	// Engine
